<?php
/**
 +------------------------------------------------------------------------------
 * 控制器调度类
 +------------------------------------------------------------------------------
 * @version   2.2
 * @author    WangXian
 * @package ephp
 * @filename app.class.php
 * @creation date 2010-8-12
 +------------------------------------------------------------------------------
 */
class app {

	public function __construct()
	{
		$path_info = $this->_path_info();
		if(! empty($path_info))
			$splits = explode('/', trim($path_info, '/'));
		else
			$splits='';
		//var_dump($path_info);
		$_GET['controller'] = empty($_GET['controller'])?'index':$_GET['controller'];
		$_GET['action'] = empty($_GET['action']) ?'index':$_GET['action'];
			
		#在保证安全的前提下，进行兼容PATH_INFO和GET方式，如果是url混合方式，则以path_info为主
		if(! empty($splits[0]) )
		{
			$_GET['controller'] = empty($splits[0])?'index':$splits[0];
			$_GET['action'] = empty($splits[1]) ?'index':$splits[1];
		}
		
		$ucount = count($splits);
		for($i=2; $i<$ucount; $i+=2)
		{
			if(!empty($splits[$i]) && !empty($splits[$i+1])) $_GET[$splits[$i]]=$splits[$i+1];
		}
		//var_dump($_GET);
		//添加request参数变量
		if(! empty($_GET))
			$_REQUEST = array_merge($_GET,$_REQUEST);
	}

	public function run()
	{
		try
		{

			$rc = new ReflectionClass($_GET['controller'] . 'Controller');
			if( $rc->hasMethod($_GET['action'] .'Action') )
			{
				$controller = $rc->newInstance();
				$method = $rc->getMethod($_GET['action'] .'Action');

				try
				{	/** 捕获系统ErrorException异常 **/
					$method->invoke($controller);
				}
				catch(ErrorException $e)
				{
					throw new ephpException($e->getMessage(), $e->getCode(), $e);
				}

			}
			else
			{
				if(! C('debug'))
				show404();
				else
				throw new ephpException($_GET['action'] ."Action()未定义，可能原因在文件controllers/". $_GET['controller'] .'Controller.php中'. $_GET['action'] .'Action()不存在！',1723);
			}
		}
		catch(ephpException $e1)
		{//捕获ephpException异常
			echo $e1;
		}

	}
	/**
     +----------------------------------------------------------
     * 处理目录 path_info,服务器必须支持path info
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	private function _path_info()
	{
		$path_info='';
		if(! empty($_SERVER['PATH_INFO'])) #冗余避免触发E_NOTICE错误；
		{
			$path_info = $_SERVER['PATH_INFO'];

			//启用url路由功能
			if( C('url_router') && !empty($path_info) ) #是否打开路由开关
			{
				$first_param = substr($path_info,1,strpos($path_info,'/',1) - 1); #获取url上的第一个参数，用于对象router中的路由规则；
				$config = include APP_PATH.'/conf/router.config.php';

				//var_dump($config[$first_param]);
				if(! empty($config[$first_param])) #冗余避免触发E_NOTICE错误；
				{
					foreach ($config[$first_param] as $v)
					{
						$count = 0; //记录成功替换的个数
						$path_info = preg_replace($v[0],$v[1],$path_info,-1,$count);
						//var_dump($path_info);

						//只要匹配上一个，则停止匹配，故在router.config.php从上到下有优先规则。
						if($count > 0) continue;

						//记录路由还原后的PATH_INFO到GET数组
						//$_GET['PATH_INFO'] = $path_info;
					}
				}
			}
			
			//去掉path_info 后缀,这里不能用trim，如果是trim则会把t也会去掉
			$html_url_subffix = C('html_url_suffix');
			if( $html_url_subffix )
				$path_info = str_replace($html_url_subffix, '', $path_info);
		}
		return $path_info;
	}
}